home *** CD-ROM | disk | FTP | other *** search
- // CmReserv.cpp
- // -----------------------------------------------------------------
- // Compendium - C++ Container Class Library
- // Copyright (C) 1992-1994, Glenn M. Poorman, All rights reserved
- // -----------------------------------------------------------------
- // In-memory data base implementation.
- // -----------------------------------------------------------------
-
- #include <cm/include/cmreserv.h>
- #include <cm/include/cmobjref.h>
- #include <cm/include/cmarray.h>
- #include <cm/include/cmassoc.h>
- #include <cm/include/cmbag.h>
- #include <cm/include/cmbintr.h>
- #include <cm/include/cmdate.h>
- #include <cm/include/cmdeque.h>
- #include <cm/include/cmhdict.h>
- #include <cm/include/cmhash.h>
- #include <cm/include/cmordarr.h>
- #include <cm/include/cmqueue.h>
- #include <cm/include/cmring.h>
- #include <cm/include/cmset.h>
- #include <cm/include/cmstack.h>
- #include <cm/include/cmtime.h>
-
-
- // Declare and initialize the static class register list.
- CmLinkedList ___cmReserve_Register_List;
- CmLinkedList* CmReserve::_classes = &___cmReserve_Register_List;
-
- // Initialize the references flag. Setting this FALSE means that multiply
- // referenced objects will be written as such. This can cause an I/O
- // performance hit so, if there are definately no multiply referenced
- // objects in the reserve, setting this to FALSE will greatly increase
- // I/O speed.
- Bool CmReserve::_references = TRUE;
-
- // Declare and initialize the static reference table.
- CmBTree ___cmReserve_Reference_Table;
- CmBTree* CmReserve::_referenceTable = &___cmReserve_Reference_Table;
-
-
- // "CmReserve" is the reserve constructor.
- //
- CmReserve::CmReserve(const char* name)
- {
- _name = name;
- _identifier = "CMRESERVE FILE";
- _roots = new CmBTreeDictionary;
- }
-
-
- // "CmReserve" is the reserve copy constructor.
- //
- CmReserve::CmReserve(const CmReserve& R)
- {
- _name = R._name;
- _identifier = R._identifier;
- _roots = new CmBTreeDictionary(*(R._roots));
- }
-
-
- // "~CmReserve" is the reserve destructor.
- //
- CmReserve::~CmReserve()
- {
- delete _roots;
- }
-
-
- // "=" assignment operator copies the entire contents of the specified
- // reserve into this reserve.
- //
- CmReserve& CmReserve::operator=(const CmReserve& R)
- {
- if (&R != this)
- {
- delete _roots;
- _name = R._name;
- _identifier = R._identifier;
- _roots = new CmBTreeDictionary(*(R._roots));
- }
- return *this;
- }
-
-
- // "exists" returns TRUE if the reserve file already exists on disk.
- //
- Bool CmReserve::exists() const
- {
- return (CmReserveFile::exists((const char*) _name));
- }
-
-
- // "addRoot" adds the specified root label and root to the root list.
- //
- Bool CmReserve::addRoot(const char* name, CmContainer* pCont)
- {
- if (!pCont) return FALSE;
-
- CmString temp(name);
- if (_roots->contains(&temp)) return FALSE;
- return _roots->add(new CmString(temp), pCont);
- }
-
-
- // "createRoot" creates a root container with the specified root name
- // and stuffs it into the root list.
- //
- CmContainer* CmReserve::createRoot(const char* name)
- {
- CmContainer *pList = getRoot(name);
- if (!pList)
- {
- pList = new CmLinkedList;
- if (!pList) return NULL;
- if (!_roots->add(new CmString(name), pList))
- {
- delete pList;
- pList = NULL;
- }
- }
- return pList;
- }
-
-
- // "totalRoots" returns the total number of roots.
- //
- int CmReserve::totalRoots() const
- {
- return _roots->size();
- }
-
-
- // "containsRoot" checks if a root with the given name exists in
- // the reserve.
- //
- Bool CmReserve::containsRoot(const char* name) const
- {
- return (getRoot(name)) ? TRUE : FALSE;
- }
-
-
- // "getRoot" finds the root at the given index in the root list and
- // returns a pointer to it.
- //
- CmContainer* CmReserve::getRoot(const char* name) const
- {
- CmString temp(name);
- return (CmContainer*) _roots->lookupObject(&temp);
- }
-
-
- // "removeRoot" removes and destroys the root with the specified
- // name in the root list.
- //
- Bool CmReserve::removeRoot(const char* name)
- {
- CmString temp(name);
- return _roots->remove(&temp);
- }
-
-
- // "removeAll" removes all roots from the reserve.
- //
- void CmReserve::removeAll()
- {
- _roots->removeAll();
- }
-
-
- // "write" writes all the objects in the reserve to an output file
- // name with the reserve name.
- //
- Bool CmReserve::write() const
- {
- CmReserveFile file((const char*) _name); // Open the file.
- if (!file) return FALSE;
-
- Bool success = file.write((const char*) _identifier); // Write identifier.
- if (success) success = _roots->write(file); // Write roots.
- file.close(); // Close the file.
- CmReserve::resetTable();
- return success;
- }
-
-
- // "read" reads the file with the reserve name into the reserve.
- //
- Bool CmReserve::read()
- {
- if (!exists()) return FALSE; // Exit if no disk file.
-
- CmReserveFile file((const char*) _name); // Open the file.
- if (!file) return FALSE;
-
- char *ident = file.read(); // Read the identifier.
- Bool success = (strcmp(ident, (const char*) _identifier) == 0);
- delete[] ident;
-
- if (success)
- {
- removeAll(); // Remove any existing roots.
- success = _roots->read(file); // Read roots.
- }
- file.close(); // Close the file.
- CmReserve::resetTable();
- return success;
- }
-
-
- // "forEach" cycles through all objects in the reserve calling the
- // specified function for each object passing in the object pointer
- // and the application-supplied data.
- //
- void CmReserve::forEach(CmQueryFunc pFunc, void* pData)
- {
- CmIterator *iterator = _roots->newIterator();
- while (!iterator->done())
- {
- CmAssociation *pAssoc = (CmAssociation*) iterator->next();
- CmContainer *pCont = (CmContainer*) pAssoc->object();
- pCont->forEach(pFunc, pData);
- }
- }
-
-
- // "forEach" cycles through all objects in the reserve calling the
- // specified object member function for each object and passing in
- // the application-supplied data.
- //
- void CmReserve::forEach(CmQueryMemFunc pFunc, void* pData)
- {
- CmIterator *iterator = _roots->newIterator();
- while (!iterator->done())
- {
- CmAssociation *pAssoc = (CmAssociation*) iterator->next();
- CmContainer *pCont = (CmContainer*) pAssoc->object();
- pCont->forEach(pFunc, pData);
- }
- }
-
-
- // "firstThat" returns the first object in the reserve that is
- // passed into the specified function and returns TRUE.
- //
- CmObject* CmReserve::firstThat(CmQueryFunc pFunc, void* pData)
- {
- CmObject *outObj = NULL;
- CmIterator *iterator = _roots->newIterator();
- while (!iterator->done() && !outObj)
- {
- CmAssociation *pAssoc = (CmAssociation*) iterator->next();
- CmContainer *pCont = (CmContainer*) pAssoc->object();
- outObj = pCont->firstThat(pFunc, pData);
- }
- return outObj;
- }
-
-
- // "firstThat" returns the first object in the reserve that is
- // passed into the specified function and returns TRUE.
- //
- CmObject* CmReserve::firstThat(CmQueryMemFunc pFunc, void* pData)
- {
- CmObject *outObj = NULL;
- CmIterator *iterator = _roots->newIterator();
- while (!iterator->done() && !outObj)
- {
- CmAssociation *pAssoc = (CmAssociation*) iterator->next();
- CmContainer *pCont = (CmContainer*) pAssoc->object();
- outObj = pCont->firstThat(pFunc, pData);
- }
- return outObj;
- }
-
-
- // "query" cycles through all objects in the reserve calling the
- // specified function for each object passing in the object pointer
- // and the application-supplied data. A return value of TRUE from
- // the function means to add that object to the output object list.
- //
- CmContainer* CmReserve::query(CmQueryFunc pFunc, void* pData)
- {
- CmLinkedList *pList = new CmLinkedList;
- CmIterator *iterator = _roots->newIterator();
- Bool success = TRUE;
- while (!iterator->done() && success)
- {
- CmAssociation *pAssoc = (CmAssociation*) iterator->next();
- CmContainer *pCont = (CmContainer*) pAssoc->object();
- CmContainer *temp = pCont->query(pFunc, pData);
- if (temp)
- {
- temp->ownsObjects(FALSE);
- success = pList->addAllFrom(temp);
- delete temp;
- }
- else
- success = FALSE;
- }
- return pList;
- }
-
-
- // "query" cycles through all objects in the reserve calling the
- // specified object member function for each object and passing in
- // the application-supplied data. A return value of TRUE from the
- // function means to add that object to the output object list.
- //
- CmContainer* CmReserve::query(CmQueryMemFunc pFunc, void* pData)
- {
- CmLinkedList *pList = new CmLinkedList;
- CmIterator *iterator = _roots->newIterator();
- Bool success = TRUE;
- while (!iterator->done() && success)
- {
- CmAssociation *pAssoc = (CmAssociation*) iterator->next();
- CmContainer *pCont = (CmContainer*) pAssoc->object();
- CmContainer *temp = pCont->query(pFunc, pData);
- if (temp)
- {
- temp->ownsObjects(FALSE);
- success = pList->addAllFrom(temp);
- delete temp;
- }
- else
- success = FALSE;
- }
- return pList;
- }
-
-
- // "fileIdentifier" opens the specified file, reads the identifier
- // string, and returns it. The application must delete the string.
- //
- char* CmReserve::fileIdentifier(const char* name)
- {
- CmReserveFile file(name);
- if (!file) return NULL;
-
- char *file_str = file.read();
- file.close();
- return file_str;
- }
-
-
- // "registerClass" registers the specified class object as "storable"
- // with the reserve.
- //
- Bool CmReserve::registerClass(CmObject* pObj)
- {
- return (getClassRegister(pObj->isA())) ? FALSE : _classes->add(pObj);
- }
-
-
- // "getClassRegister" returns a pointer to the registered class of
- // the specified type.
- //
- CmObject* CmReserve::getClassRegister(const char* name)
- {
- CmObject *out = NULL;
- CmIterator *iterator = CmReserve::_classes->newIterator();
- while (!iterator->done() && !out)
- {
- CmObject *pObj = iterator->next();
- if (pObj->isA(name)) out = pObj;
- }
- delete iterator;
- return out;
- }
-
-
- // "initialize" registers all of the Compendium object classes
- // with the reserve.
- //
- void CmReserve::initialize()
- {
- registerClass(new CmArray);
- registerClass(new CmAssociation(NULL, NULL));
- registerClass(new CmBag);
- registerClass(new CmBinaryTree);
- registerClass(new CmBTree);
- registerClass(new CmBTreeDictionary);
- registerClass(new CmDate);
- registerClass(new CmDeque);
- registerClass(new CmHashDictionary);
- registerClass(new CmHashTable);
- registerClass(new CmLinkedList);
- registerClass(new CmOrderedArray);
- registerClass(new CmQueue);
- registerClass(new CmRing);
- registerClass(new CmSet);
- registerClass(new CmStack);
- registerClass(new CmString);
- registerClass(new CmTime);
- }
-
-
- // "resetTable" resets the reference table.
- //
- void CmReserve::resetTable()
- {
- CmReserve::_referenceTable->removeAll();
- }
-
-
- // "maintainReferences" sets the references flag.
- //
- void CmReserve::maintainReferences(Bool flag)
- {
- CmReserve::_references = flag;
- }
-
-
- // "maintainReferences" returns the value of the references flag.
- //
- Bool CmReserve::maintainReferences()
- {
- return CmReserve::_references;
- }
-
-
- // "addToTable" adds the specified object to the table.
- //
- Bool CmReserve::addToTable(CmObject* pObj, int policy)
- {
- int ky = CmReserve::_referenceTable->size();
- CmObjectReference *pR = new CmObjectReference(ky, pObj);
- CmObjectReference::compareBy(policy);
- return CmReserve::_referenceTable->add(pR);
- }
-
-
- // "getFromTable" returns the object in the table associated with the
- // specified key.
- //
- CmObject* CmReserve::getFromTable(int key)
- {
- CmObjectReference::compareBy(CmObjectReference::KEYS);
- CmObjectReference temp(key);
- CmObjectReference* pR = (CmObjectReference*)
- CmReserve::_referenceTable->lookup(&temp);
- return (pR) ? pR->object() : NULL;
- }
-
-
- // "getFromTable" returns the key in the table associated with the
- // specified object.
- //
- int CmReserve::getFromTable(CmObject *pObj)
- {
- CmObjectReference::compareBy(CmObjectReference::OBJECTS);
- CmObjectReference temp(pObj);
- CmObjectReference* pR = (CmObjectReference*)
- CmReserve::_referenceTable->lookup(&temp);
- return (pR) ? pR->key() : -1;
- }
-